package DAO;

import Entidades.Emissor;
import Entidades.Entrada;
import Entidades.PwDSM;
import Entidades.Receptor;
import Entidades.Saida;
import Entidades.TipoEntrada;
import Entidades.TipoSaida;
import Entidades.Usuario;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.swing.JOptionPane;

public class Dao {

    public Connection getConnection(){
        try {
            //System.out.println("Conectando...");
            Class.forName("net.sourceforge.jtds.jdbc.Driver");
            //Connection con = DriverManager.getConnection("jdbc:jtds:sqlserver://172.16.0.209/evsdsv", "evsdsv", "evsdsv");
            Connection con = DriverManager.getConnection("jdbc:jtds:sqlserver://172.16.0.203/SCDO", "scdo", "Admin1234");
            System.out.println("Conectado a VirtualBD/SCDO");
            return con;
        } catch (SQLException ex) {
            JOptionPane.showMessageDialog(null, ex);
            return null;
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }

    public Statement getStatement() throws SQLException{
        return getConnection().createStatement();
    }

    public PreparedStatement getStatement(String st) throws SQLException{
        return getConnection().prepareStatement(st);
    }

    public ResultSet executeQuery(String query, Object... params) throws SQLException{
        PreparedStatement ps = getStatement(query);        
        for (int i = 0; i < params.length; i++){
            ps.setObject(i+1, params[i]);
        }        
        return ps.executeQuery();
    }

    public int executaComando(String query, Object... params) throws SQLException{
        PreparedStatement ps = getStatement(query);
        for (int i = 0; i < params.length; i++){
            ps.setObject(i+1, params[i]);
        }
        int result = ps.executeUpdate();
        return result;
    }
    
    public void addUser(String nome, String login, String senha) throws SQLException, BadPaddingException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchAlgorithmException, InvalidAlgorithmParameterException{
        //System.out.println(senha);
        String senhaCriptografada = PwDSM.encrypt(senha);
        //System.out.println(senhaCriptografada);
        String query = "EXEC dbo.sp_cadastrarUsuario ?, ?, ?"; //nome, login, senha
        executaComando(query, nome, login, senhaCriptografada);
    }
    
    public void alterarSenha(String loginUsuario, String novaSenha) throws SQLException{
        try {
            String senha;
            senha = PwDSM.encrypt(novaSenha);
            String query = "UPDATE USUARIOS SET SENHA = ? WHERE LOGIN = ?";
            executaComando(query, senha, loginUsuario);
        } catch (BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException | InvalidAlgorithmParameterException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    public boolean validarLogon(String loginUsuario, String senhaUsuario){
        boolean toReturn = false;
        String senha;
        try {
            senha = PwDSM.encrypt(senhaUsuario);
            try (ResultSet rs = executeQuery("SELECT * FROM USUARIOS WHERE LOGIN=? AND SENHA = ? AND STATUS = 0", loginUsuario, senha)) {
                if (rs.next()){                    
                    toReturn = true;
                } else {
                    System.out.println("Falso");
                }
            }
        } catch (SQLException | BadPaddingException | NoSuchPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchAlgorithmException | InvalidAlgorithmParameterException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return toReturn;
    }    
    
    public Usuario obterDadosUsuario(String loginUsuario) throws SQLException{
        
        Usuario usuario;
        try (ResultSet rs = executeQuery("SELECT ID, NOME, SENHA, STATUS, DT_CRIACAO, PERFIL  FROM dbo.USUARIOS WHERE LOGIN=?", loginUsuario)) {
            usuario = new Usuario();
            while (rs.next()){
                usuario.setId(rs.getInt("ID"));
                usuario.setNome(rs.getString("NOME"));
                usuario.setSenha(rs.getString("SENHA"));
                usuario.setStatus(rs.getInt("STATUS"));
                usuario.setDt_criacao(rs.getDate("DT_CRIACAO"));
                usuario.setPerfil(rs.getString("PERFIL"));
            }   usuario.setLogin(loginUsuario);
        }
        return usuario;
    }
    public List<TipoEntrada> listarTipoEntrada(){
        List<TipoEntrada> entradas = new ArrayList<>();
        ResultSet rs;
        try {
            rs = executeQuery("EXEC dbo.sp_listaTipoEntrada");            
            while (rs.next()){
                TipoEntrada te = new TipoEntrada();
                te.setId(rs.getInt("id"));
                te.setNome(rs.getString("nome"));
                te.setDescricao(rs.getString("descricao"));
                entradas.add(te);
            }        
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return entradas;
    }

    public List<TipoSaida> listarTipoSaida(){
        List<TipoSaida> saidas = new ArrayList<>();
        ResultSet rs;
        try {
            rs = executeQuery("EXEC dbo.sp_listaTipoSaida");            
            while (rs.next()){
                TipoSaida s = new TipoSaida();
                s.setId(rs.getInt("id"));
                s.setNome(rs.getString("nome"));
                s.setDescricao(rs.getString("descricao"));
                saidas.add(s);
            }        
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return saidas;
    }    
    
    public List<Emissor> listarEmissores(){
        List<Emissor> emissores = new ArrayList<>();
        ResultSet rs;
        try {
            rs = executeQuery("EXEC dbo.sp_listaEmissores");        
            while (rs.next()){
                Emissor e = new Emissor();
                e.setId(rs.getInt("id"));
                e.setNome(rs.getString("nome"));
                emissores.add(e);
            }        
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return emissores;
    }

    public List<Receptor> listarReceptores(){
        List<Receptor> receptores = new ArrayList<>();
        ResultSet rs;
        try {
            rs = executeQuery("EXEC dbo.sp_listaReceptores");        
            while (rs.next()){
                Receptor r = new Receptor();
                r.setId(rs.getInt("id"));
                r.setNome(rs.getString("nome"));
                receptores.add(r);
            }        
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return receptores;
    }    
    
    public Entrada lancarEntrada(Entrada entrada) throws SQLException, ParseException{
        int idUsuario = entrada.getIdUsuario();
        String dtReferencia = new SimpleDateFormat("yyyy-MM-dd").format(entrada.getDtReferencia());
        int idEmissor = entrada.getIdEmissor();
        int idTipo = entrada.getIdTipo();
        Double valor = entrada.getValor();
        String descricao = entrada.getDescricao();
        String query = "EXEC dbo.sp_lancarEntrada ?, ?, ?, ?, ?, ?";
        ResultSet rs = executeQuery(query, idUsuario, dtReferencia, idEmissor, idTipo, valor, descricao);
        Entrada e = new Entrada();
        while (rs.next()) {            
            e.setNomeTipoEntrada(rs.getString("nomeTipoEntrada"));
            e.setNomeEmissor(rs.getString("nomeEmissor"));
            e.setValor(rs.getDouble("valor"));
            e.setDtReferencia(new SimpleDateFormat("dd/MM/yyyy").parse(rs.getString("dtReferencia")));
        }
        return e;
    }

    public void alterarEntrada(Entrada entrada){
        String id = entrada.getId();
        int idUsuario = entrada.getIdUsuario();
        String dtReferencia = new SimpleDateFormat("yyyy-MM-dd").format(entrada.getDtReferencia());
        int idEmissor = entrada.getIdEmissor();
        int idTipo = entrada.getIdTipo();
        Double valor = entrada.getValor();
        String descricao = entrada.getDescricao();
        String query = "EXEC dbo.sp_alterarEntrada ?, ?, ?, ?, ?, ?, ?";        
        try {
            executaComando(query, id, idUsuario, dtReferencia, idEmissor, idTipo, valor, descricao);
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, ex);
        }
    }    
    
    public Saida lancarSaida(Saida saida) throws SQLException, ParseException{
        int idUsuario = saida.getIdUsuario();
        String dtReferencia = new SimpleDateFormat("yyyy-MM-dd").format(saida.getDtReferencia());
        int idReceptor = saida.getIdReceptor();
        int idTipo = saida.getIdTipo();
        Double valor = saida.getValor();
        String descricao = saida.getDescricao();
        String query = "EXEC dbo.sp_lancarSaida ?, ?, ?, ?, ?, ?";
        ResultSet rs = executeQuery(query, idUsuario, dtReferencia, idReceptor, idTipo, valor, descricao);
        Saida s = new Saida();
        while (rs.next()) {            
            s.setNomeTipoSaida(rs.getString("nomeTipoEntrada"));
            s.setNomeReceptor(rs.getString("nomeEmissor"));
            s.setValor(rs.getDouble("valor"));
            s.setDtReferencia(new SimpleDateFormat("dd/MM/yyyy").parse(rs.getString("dtReferencia")));
        }
        return s;
    }
    
    public List<Usuario> listarUsuarios(){
        List<Usuario> usuarios = new ArrayList<>();
        String query = "EXEC dbo.sp_listaUsuarios";
        ResultSet rs;
        try {
            rs = executeQuery(query);
            while (rs.next()) {            
                Usuario u = new Usuario();
                u.setId(rs.getInt("ID"));
                u.setNome(rs.getString("NOME"));
                usuarios.add(u);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
        }
        return usuarios;
    }
    
    public List<Entrada> listarEntradas(Date dtRegistroIni, Date dtRegistroFim, Date dtReferenciaIni, Date dtReferenciaFim, int idEmissor, int idTipo, int idUsuario){
        java.sql.Date dtRegIni = null;
        java.sql.Date dtRegFim = null;
        java.sql.Date dtRefIni = null;
        java.sql.Date dtRefFim = null;
        
        if(dtReferenciaIni != null) dtRefIni = new java.sql.Date(dtReferenciaIni.getTime());
        if(dtReferenciaFim != null) dtRefFim = new java.sql.Date(dtReferenciaFim.getTime());        
        if(dtRegistroIni != null) dtRegIni = new java.sql.Date(dtRegistroIni.getTime());
        if(dtRegistroFim != null) dtRegFim = new java.sql.Date(dtRegistroFim.getTime());        
        
        List<Entrada> entradas = new ArrayList<>();
        String query = "EXEC dbo.sp_consultarLancamentoEntrada ?,?,?,?,?,?,?";
        ResultSet rs;
        int x = 0;
        try {
            rs = executeQuery(query, dtRefIni, dtRefFim, dtRegIni, dtRegFim, idEmissor, idTipo, idUsuario);            
            while (rs.next()) {            
                Entrada e = new Entrada();
                x++;
                e.setIdInterno(x);
                e.setId(rs.getString("id"));
                e.setDtRegistro(rs.getTimestamp("dtRegistro"));
                e.setIdUsuario(rs.getInt("idUsuario"));
                e.setNomeUsuario(rs.getString("nomeUsuario"));
                e.setDtAtualizacao(rs.getDate("dtAtualizacao"));
                e.setIdUsuarioAtualizacao(rs.getInt("idUsuarioAtualizacao"));
                e.setNomeUsuarioAtualizacao(rs.getString("nomeUsuarioAtualizacao"));
                e.setDtReferencia(rs.getDate("dtReferencia"));
                e.setIdEmissor(rs.getInt("idEmissor"));
                e.setNomeEmissor(rs.getString("nomeEmissor"));
                e.setIdTipo(rs.getInt("idTipoEntrada"));
                e.setNomeTipoEntrada(rs.getString("nomeTipoEntrada"));
                e.setValor(rs.getDouble("valor"));
                e.setStatus(rs.getString("status"));
                e.setDescricao(rs.getString("descricao"));
                entradas.add(e);
            }
        } catch (SQLException ex) {
            Logger.getLogger(Dao.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, ex);
        }            
        return entradas;
    }
    
    
}
